<template>
    <div class="container" style="position: absolute; top: -9999px; left: -9999px; width: 512px; height: 512px;">
        <!-- 隐藏imageLoaders的UI，只保留后台逻辑 -->
        <div class="input-section" style="display: none;">
            <el-input v-model="studyInstanceUid" placeholder="Study Instance UID"
                style="width: 300px; margin-right: 10px;" />
            <el-input v-model="seriesInstanceUid" placeholder="Series Instance UID"
                style="width: 300px; margin-right: 10px;" />
            <el-button @click="loadDicomSeries" type="primary" :disabled="!isInitialized" :loading="!isInitialized">
                {{ isInitialized ? '加载DICOM序列' : '初始化中...' }}
            </el-button>
        </div>

        <input type="file" name="file" id="file" multiple @change="handleFileSelect" style="display: none;">
        <button @click="createNetworkImageIds" style="display: none;">使用网络资源</button>

        <!-- 离屏视口元素，用于后台处理 -->
        <div class="content" id="capture" ref="contentRef">
            <div class="viewport" ref="viewportRef"></div>
        </div>
    </div>
</template>

<script setup>
// 定义props
const props = defineProps({
    studyId: {
        type: Number,
        required: false
    },
    studyUid: {
        type: String,
        required: false
    },
    seriesUid: {
        type: String,
        required: false
    }
})

// 定义emits
const emit = defineEmits(['series-loaded'])

import { ref, onMounted, computed, watch } from 'vue'
import {
    createImageIdsAndCacheMetaData,
    initLib,
    initRenderingEngine,
    loadAndViewDcmFiles,
    enableStackPrefetch,
    initTools
} from '@/utils/dicom/cornerstoneCtrl'
import {
    imageLoader,
    metaData,
    EVENTS,
    getRenderingEngine
} from '@cornerstonejs/core'
import cornerstoneDICOMImageLoader from '@cornerstonejs/dicom-image-loader'
import { determineScanOrientation } from '@/utils/dicom/determineScanOrientation'
import html2canvas from 'html2canvas'
import tools from '@/const/tools.js'
import { DicomDataService } from '@/api/pacs/dicom/dicomService.js'

// 创建DicomDataService实例
const dicomService = new DicomDataService()
const wadoRsRoot = ''
const baseUrl = import.meta.env.VITE_APP_BASE_API

let toolGroup = null
let viewportId = 'CT_STACK'
let renderingEngineId = 'myRenderingEngine'
let toolGroupId = 'STACK_TOOL_GROUP_ID'
let viewPort = null
let renderingEngine = null
let files = ref([])
let imageIds = ref([])
let currentIndex = ref(0)
let sliderValue = ref(0)

// 使用props或默认值
const studyUnionId = ref(props.studyId || null)
const studyInstanceUid = ref(props.studyUid || '')
const seriesInstanceUid = ref(props.seriesUid || '')

// 初始化状态标志
const isInitialized = ref(false)

// 加载状态控制
let isLoading = false
let loadAttempts = 0
const MAX_LOAD_ATTEMPTS = 3

// 计算属性检测props变化
const propsReady = computed(() => {
    return !!(props.studyId && props.studyUid && props.seriesUid)
})

// 监听计算属性变化
watch(propsReady, (isReady) => {
    if (isReady && !isLoading) {
        studyUnionId.value = props.studyId
        studyInstanceUid.value = props.studyUid
        seriesInstanceUid.value = props.seriesUid
        loadDicomSeries()
    }
}, { immediate: true })

// 视图DOM引用
const viewportRef = ref(null)

// 左侧视图DOM引用
const LeftViewportRef = ref(null)

// 上一个
const prevItem = () => {
    if (currentIndex.value > 0) {
        currentIndex.value--
        onItemChanged(currentIndex.value, files.value[currentIndex.value])
    }
}

// 下一个
const nextItem = () => {
    if (currentIndex.value < imageIds.value.length - 1) {
        currentIndex.value++
        onItemChanged(currentIndex.value, files.value[currentIndex.value])
    }
}

// 滑块改变时
const handleSliderChange = (value) => {
    if (value > 0) {
        currentIndex.value = imageIds.value.length - value;
        onItemChanged(currentIndex.value, files.value[currentIndex.value])
    }
}

const detailList = ref([
    {
        label: '编号',
        value: '',
        id: 'id'
    },
    {
        label: '扫描方向',
        value: '',
        id: 'scanDirection'
    },
    {
        label: '体位显示',
        value: {},
        id: 'bodyPosition'
    },
    {
        label: '用户名称',
        value: 'Anonymous',
        id: 'username'
    },
    {
        label: '阶段',
        value: '',
        id: 'stage'
    },
    {
        label: 'Columns',
        value: '',
        id: 'columns'
    }, {
        label: 'Rows',
        value: '',
        id: 'rows'
    },
    {
        label: '时间',
        value: '',
        id: 'timestamp'
    },
    {
        label: '窗宽',
        value: '',
        id: 'windowWidth'
    },
    {
        label: '窗位',
        value: '',
        id: 'windowCenter'
    },
    {
        label: '文件名',
        value: '',
        id: 'filename'
    },
    {
        label: '像素间距',
        value: '',
        id: 'spacing'
    }
])

// 将detailList转换成对象格式
const detailListObj = computed(() => {
    return detailList.value.reduce((acc, item) => {
        acc[item.id] = item
        return acc
    }, {})
})

// 更新detail值的方法
const updateDetail = (id, newValue) => {
    const index = detailList.value.findIndex(item => item.id === id)
    if (index !== -1) {
        detailList.value[index].value = newValue
    }
}

// 批量更新detail的方法
const updateDetails = (updates) => {
    Object.entries(updates).forEach(([id, value]) => {
        updateDetail(id, value)
    })
}

onMounted(async () => {
    async function run() {
        try {
            // 延迟100ms，确保DicomViewer先初始化
            await new Promise(resolve => setTimeout(resolve, 100))

            // 初始化库
            await initLib()

            // 检查DOM元素
            if (!viewportRef.value) {
                throw new Error('Viewport DOM 元素未找到')
            }

            // 初始化渲染引擎
            const res = initRenderingEngine({
                element: viewportRef.value,
                renderingEngineId,
                viewportId
            })

            if (!res.viewPort || !res.renderingEngine) {
                throw new Error('渲染引擎初始化失败')
            }

            viewPort = res.viewPort
            renderingEngine = res.renderingEngine

            // 初始化工具
            toolGroup = initTools(toolGroupId, {
                [tools.scroller]: true
            }, viewportId)

            // 标记初始化完成
            isInitialized.value = true

        } catch (error) {
            console.error('Cornerstone 初始化失败:', error)
        }
    }

    await run()
})

// 添加文件上传函数
const uploadFileToBackend = async (file) => {
    try {
        const formData = new FormData();
        formData.append('file', file);

        const response = await fetch(baseUrl + '/api/dicom/upload', {
            method: 'POST',
            body: formData
        });

        const result = await response.json();

        if (result.success) {
            console.log('文件上传成功:', result);
        } else {
            console.error('文件上传失败:', result.message);
        }

        return result;
    } catch (error) {
        console.error('上传过程中发生错误:', error);
        throw error;
    }
};

// 修改handleFileSelect函数，添加上传功能
const handleFileSelect = async (evt) => {
    evt.stopPropagation();
    evt.preventDefault();

    if (evt.target.files.length === 0) return;

    files.value = evt.target.files;
    currentIndex.value = 0;

    // 1. 先上传文件到后端
    try {
        for (let i = 0; i < files.value.length; i++) {
            await uploadFileToBackend(files.value[i]);
        }
    } catch (error) {
        console.error('文件上传失败，但继续本地显示');
    }

    // 2. 然后进行本地显示（原有逻辑）
    updateDetails({
        timestamp: Date.now(),
    });

    loadAndViewDcmFiles(files.value, viewPort).then((ids) => {
        imageIds.value = ids;
        sliderValue.value = ids.length;

        ids.forEach((id, i) => {
            viewPort.setImageIdIndex(i);
        });

        onItemChanged(currentIndex.value, files.value[currentIndex.value]);
    });
};

/**
 * 创建网络图像
 */
const createNetworkImageIds = async () => {
    const _imageIds = await createImageIdsAndCacheMetaData({
        StudyInstanceUID,
        SeriesInstanceUID,
        wadoRsRoot,
    });
    await viewPort.setStack(_imageIds)
    enableStackPrefetch(viewPort)
    toolGroup.addViewport(viewportId, renderingEngineId);
    viewPort.render();
    imageIds.value = _imageIds

    viewportRef.value.addEventListener(EVENTS.STACK_NEW_IMAGE, (evt) => {
        const { imageIdIndex } = evt.detail;
        currentIndex.value = imageIdIndex
        onItemChanged(currentIndex.value)
    });
}

// 切换图像，兼容本地文件和网络图像
const onItemChanged = async (id, file) => {
    sliderValue.value = imageIds.value.length - id;
    updateDetails({
        id: `${id}`
    })

    if (file) {
        updateDetails({
            filename: file.name,
            timestamp: file.lastModified,
        })
    }

    // 使用 StackViewport 的方法设置当前图像
    if (typeof viewPort.setImageIdIndex === 'function') {
        viewPort.setImageIdIndex(id);
    }

    // 重新渲染
    if (typeof viewPort.render === 'function') {
        viewPort.render();
    }

    // 等待图像数据加载
    await new Promise(resolve => setTimeout(resolve, 200));

    try {
        if (typeof viewPort.getImageData === 'function') {
            const imageData = viewPort.getImageData();

            if (imageData) {
                let imageId = imageIds.value[id];
                const voiLutModule = metaData.get('voiLutModule', imageId);

                updateDetails({
                    columns: imageData.dimensions[1],
                    rows: imageData.dimensions[0],
                    windowWidth: voiLutModule.windowWidth,
                    windowCenter: voiLutModule.windowCenter,
                    spacing: imageData.spacing.join('\\'),
                    stage: imageData.metadata.Modality,
                    scanDirection: determineScanOrientation(imageData.direction).label,
                    bodyPosition: determineScanOrientation(imageData.direction).bodyPosition
                });
            } else {
                // 尝试重新渲染并再次获取
                viewPort.render();
                await new Promise(resolve => setTimeout(resolve, 100));

                const retryImageData = viewPort.getImageData();
                if (retryImageData) {
                    let imageId = imageIds.value[id];
                    const voiLutModule = metaData.get('voiLutModule', imageId);

                    updateDetails({
                        columns: retryImageData.dimensions[1],
                        rows: retryImageData.dimensions[0],
                        windowWidth: voiLutModule.windowWidth,
                        windowCenter: voiLutModule.windowCenter,
                        spacing: retryImageData.spacing.join('\\'),
                        stage: retryImageData.metadata.Modality,
                        scanDirection: determineScanOrientation(retryImageData.direction).label,
                        bodyPosition: determineScanOrientation(retryImageData.direction).bodyPosition
                    });
                }
            }
        }
    } catch (error) {
        console.warn('获取图像数据失败:', error);
    }
}

// 更新详细信息
const updateDetailInfo = () => {
    if (imageIds.value.length > 0 && currentIndex.value >= 0) {
        onItemChanged(currentIndex.value, files.value[currentIndex.value])
    }
}

const saveAsImage = () => {
    const captureElement = document.getElementById('capture');
    html2canvas(captureElement).then(canvas => {
        const image = canvas.toDataURL('image/png');
        let filename = detailListObj.value.filename.value.split('.')[0];
        const link = document.createElement('a');
        link.href = image;
        link.download = `${filename}.png`;
        link.click();
    });
}

/**
 * 注册七牛云图像加载器
 */
function registerQiniuImageLoader() {
  try {
    imageLoader.unregisterImageLoader('qiniu');
  } catch (e) {
    // 忽略错误
  }

  imageLoader.registerImageLoader('qiniu', (imageId) => {
    const loadPromise = new Promise(async (resolve, reject) => {
      try {
        const url = imageId.replace('qiniu:', '');
        
        if (!url || url === 'qiniu:') {
          throw new Error('无效的图像URL: ' + url);
        }

        console.log('开始加载七牛云图像:', url);
        const arrayBuffer = await dicomService.fetchDicomFromQiniu(url);

        if (!arrayBuffer || arrayBuffer.byteLength === 0) {
          throw new Error('下载的DICOM数据为空或大小为0');
        }

        console.log('成功获取DICOM数据，大小:', arrayBuffer.byteLength, 'bytes');

        // 使用wadouri加载器
        const blob = new Blob([arrayBuffer], { type: 'application/dicom' });
        const blobUrl = URL.createObjectURL(blob);
        const tempImageId = `wadouri:${blobUrl}`;
        
        console.log('使用wadouri加载器，临时imageId:', tempImageId);
        
        try {
          const imageLoadObject = cornerstoneDICOMImageLoader.wadouri.loadImage(tempImageId);
          const image = await imageLoadObject.promise;
          console.log('通过wadouri加载器加载成功');
          
          URL.revokeObjectURL(blobUrl);
          resolve(image);
        } catch (wadoError) {
          console.error('wadouri加载器失败:', wadoError);
          URL.revokeObjectURL(blobUrl);
          reject(wadoError);
        }

      } catch (error) {
        console.error('七牛云图像加载失败:', error);
        reject(error);
      }
    });

    return {
      promise: loadPromise,
      cancelFn: () => {
        console.log('取消图像加载');
      }
    };
  });
}

/**
 * 加载DICOM序列函数
 */
async function loadDicomSeries() {
    // 防止重复加载
    if (isLoading) {
        console.log('加载正在进行中，跳过此次调用');
        return;
    }
    
    // 检查最大尝试次数
    if (loadAttempts >= MAX_LOAD_ATTEMPTS) {
        console.error('已达到最大加载尝试次数，停止加载');
        return;
    }
    
    loadAttempts++;
    isLoading = true;
    
    try {
        console.log(`开始加载DICOM序列 (尝试 ${loadAttempts}/${MAX_LOAD_ATTEMPTS}):`, {
            studyUnionId: studyUnionId.value,
            seriesInstanceUid: seriesInstanceUid.value
        });

        // 检查初始化状态
        if (!isInitialized.value || !viewPort) {
            console.log('等待初始化...');
            setTimeout(() => {
                if (isInitialized.value && viewPort) {
                    loadDicomSeries()
                }
            }, 1000)
            return
        }

        // 验证输入参数
        if (!studyUnionId.value || !seriesInstanceUid.value) {
            console.warn('缺少必要的参数: studyUnionId 或 seriesInstanceUid');
            return
        }

        // 1. 从后端获取图像信息和七牛云配置
        console.log('从后端获取图像信息...');
        const seriesData = await dicomService.createImageIds(
            studyUnionId.value,
            seriesInstanceUid.value
        )

        if (!seriesData || !seriesData.imageIds || seriesData.imageIds.length === 0) {
            throw new Error('从后端获取的图像ID列表为空');
        }

        console.log('获取到图像ID列表，数量:', seriesData.imageIds.length, '第一个ID:', seriesData.imageIds[0]);

        // 2. 注册自定义图像加载器
        console.log('注册自定义图像加载器...');
        registerQiniuImageLoader()

        // 3. 设置图像ID列表
        imageIds.value = seriesData.imageIds

        // 4. 简化加载流程
        if (imageIds.value.length > 0) {
            console.log('开始设置图像堆栈...');

            // 使用更简单的方法设置堆栈
            try {
                // 直接设置堆栈
                viewPort.setStack(imageIds.value);
                console.log('图像堆栈设置完成');

                // 启用堆栈预加载
                enableStackPrefetch(viewPort);
                console.log('堆栈预加载已启用');

                // 添加工具组到视口
                if (toolGroup) {
                    toolGroup.addViewport(viewportId, renderingEngineId);
                    console.log('工具组已添加到视口');
                }

                // 设置初始图像索引
                viewPort.setImageIdIndex(0);
                console.log('初始图像索引设置为 0');

                // 设置默认窗宽窗位
                viewPort.setProperties({
                    voiRange: {
                        windowWidth: 400,
                        windowCenter: 40
                    }
                });
                console.log('设置默认窗宽窗位');

                // 渲染视口
                viewPort.render();
                console.log('视口渲染完成');

                // 设置初始状态
                sliderValue.value = imageIds.value.length;
                currentIndex.value = 0;

                // 监听图像切换事件
                if (viewportRef.value && !viewportRef.value._hasStackListener) {
                    viewportRef.value.addEventListener(EVENTS.STACK_NEW_IMAGE, (evt) => {
                        const { imageIdIndex } = evt.detail;
                        currentIndex.value = imageIdIndex;
                        onItemChanged(currentIndex.value);
                    });
                    viewportRef.value._hasStackListener = true;
                    console.log('图像切换事件监听器已添加');
                }

                // 等待图像加载完成后再更新详细信息
                setTimeout(() => {
                    updateDetailInfo();
                    console.log('详细信息已更新');
                }, 1000);

                // 触发series-loaded事件
                emit('series-loaded', {
                    imageIds: imageIds.value,
                    seriesData: seriesData,
                    currentIndex: currentIndex.value
                });

                console.log('DICOM序列加载完成');

            } catch (error) {
                console.error('设置堆栈时出错:', error);
                throw error;
            }

        } else {
            console.error('没有找到图像数据');
            alert('没有找到图像数据，请检查 Study 和 Series UID');
        }

    } catch (error) {
        console.error('加载DICOM序列失败:', error);
        alert('加载DICOM序列失败: ' + error.message);
    } finally {
        isLoading = false;
    }
}
</script>

<style scoped>
/* 滚动条样式 */
::v-deep .el-slider.is-vertical {
    width: 100%;

    .el-slider__runway {
        margin: 0 !important;
        width: 20px;
        position: absolute;
        bottom: 0;
        background-color: transparent;

        .el-slider__button-wrapper {
            height: 20px !important;
            width: 20px !important;
            left: 0 !important;
            transform: translateY(0);
            bottom: 0;

            .el-slider__button {
                border-radius: 0;
                border: none;
                background-color: var(--slider-color);
                vertical-align: top;
            }

            .el-slider__button.dragging,
            .el-slider__button.hover,
            .el-slider__button:hover {
                transform: scale(1) !important;
            }
        }
    }
}

::v-deep .el-slider__bar {
    background-color: transparent;
}

.container {
    width: 100%;
    height: 100%;
    padding: 20px;

    .content {
        margin-top: 10px;
        position: relative;
        width: 500px;
        height: 500px;

        .viewport {
            width: 100%;
            height: 100%;
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background-color: black !important;
        }

        .viewport canvas {
            width: 100% !important;
            height: 100% !important;
            display: block !important;
        }

        .slider {
            width: 20px;
            position: absolute;
            right: -20px;
            top: 0;
            bottom: 0;
            background-color: var(--slider-runway-color);
        }

        .detail {
            flex: 1
        }
    }
}
</style>